/*
 *  ati.h
 *
 *  Created by Slice on 19.02.12.
 *
 *  the code ported from Chameleon project as well as from RadeonFB by Joblo and RadeonHD by dong
 *  big thank to Islam M. Ahmed Zaid for the updating the collection
 */

#include "Platform.h"  //this include needed for Uefi types
#include "ati_reg.h"

#define OFFSET_TO_GET_ATOMBIOS_STRINGS_START 0x6e
#define DATVAL(x)   {kPtr, sizeof(x), (UINT8 *)x}
#define STRVAL(x)   {kStr, sizeof(x)-1, (UINT8 *)x}
#define BYTVAL(x)   {kCst, 1, (UINT8 *)(UINTN)x}
#define WRDVAL(x)   {kCst, 2, (UINT8 *)(UINTN)x}
#define DWRVAL(x)   {kCst, 4, (UINT8 *)(UINTN)x}
// QWRVAL would work only in 64 bit
//#define QWRVAL(x)   {kCst, 8, (UINT8 *)(UINTN)x}
#define NULVAL    {kNul, 0, (UINT8 *)NULL}


/*Typedefs ENUMS*/
typedef enum {
 kNul,
 kStr,
 kPtr,
 kCst
} type_t;

typedef enum {
 CHIP_FAMILY_UNKNOW,
 /* Old */
 CHIP_FAMILY_R420,
 CHIP_FAMILY_R423,
 CHIP_FAMILY_RV410,
 CHIP_FAMILY_RV515,
 CHIP_FAMILY_R520,
 CHIP_FAMILY_RV530,
 CHIP_FAMILY_RV560,
 CHIP_FAMILY_RV570,
 CHIP_FAMILY_R580,
 /* IGP */
 CHIP_FAMILY_RS600,
 CHIP_FAMILY_RS690,
 CHIP_FAMILY_RS740,
 CHIP_FAMILY_RS780,
 CHIP_FAMILY_RS880,
 /* R600 */
 CHIP_FAMILY_R600,
 CHIP_FAMILY_RV610,
 CHIP_FAMILY_RV620,
 CHIP_FAMILY_RV630,
 CHIP_FAMILY_RV635,
 CHIP_FAMILY_RV670,
 /* R700 */
 CHIP_FAMILY_RV710,
 CHIP_FAMILY_RV730,
 CHIP_FAMILY_RV740,
 CHIP_FAMILY_RV770,
 CHIP_FAMILY_RV772,
 CHIP_FAMILY_RV790,
 /* Evergreen */
 CHIP_FAMILY_CEDAR,
 CHIP_FAMILY_CYPRESS,
 CHIP_FAMILY_HEMLOCK,
 CHIP_FAMILY_JUNIPER,
 CHIP_FAMILY_REDWOOD,
 /* Northern Islands */
 CHIP_FAMILY_BARTS,
 CHIP_FAMILY_CAICOS,
 CHIP_FAMILY_CAYMAN,
 CHIP_FAMILY_TURKS,
 /* Southern Islands */
 CHIP_FAMILY_PALM,
 CHIP_FAMILY_SUMO,
 CHIP_FAMILY_SUMO2,
 CHIP_FAMILY_ARUBA,
 CHIP_FAMILY_TAHITI,
 CHIP_FAMILY_PITCAIRN,
 CHIP_FAMILY_VERDE,
 CHIP_FAMILY_OLAND,
  /* Sea Islands */
 CHIP_FAMILY_HAINAN,
 CHIP_FAMILY_BONAIRE,
 CHIP_FAMILY_KAVERI,
 CHIP_FAMILY_KABINI,
 CHIP_FAMILY_HAWAII,
 CHIP_FAMILY_MULLINS,
 /* Volcanic Islands */
 CHIP_FAMILY_TOPAZ,
 CHIP_FAMILY_AMETHYST,
 CHIP_FAMILY_TONGA,
 CHIP_FAMILY_FIJI,
 CHIP_FAMILY_CARRIZO,
 CHIP_FAMILY_TOBAGO,
 CHIP_FAMILY_ELLESMERE, /* Polaris 10 */
 CHIP_FAMILY_BAFFIN,   /* Polaris 11 */
 CHIP_FAMILY_GREENLAND, /* Polaris 12 */
 CHIP_FAMILY_VEGA10,   /* Vega 10 */
 CHIP_FAMILY_LAST
} ati_chip_family_t;

typedef struct {
 const CHAR8  *name;
 UINT8   ports;
} card_config_t;

typedef enum {
 kNull,
 /* OLDController */
 kWormy,
 kAlopias,
 kCaretta,
 kKakapo,
 kKipunji,
 kPeregrine,
 kRaven,
 kSphyrna,
 /* AMD2400Controller */
 kIago,
 /* AMD2600Controller */
 kHypoprion,
 kLamna,
 /* AMD3800Controller */
 kMegalodon,
 kTriakis,
 /* AMD4600Controller */
 kFlicker,
 kGliff,
 kShrike,
 /* AMD4800Controller */
 kCardinal,
 kMotmot,
 kQuail,
 /* AMD5000Controller */
 kDouc,
 kLangur,
 kUakari,
 kZonalis,
 kAlouatta,
 kHoolock,
 kVervet,
 kBaboon,
 kEulemur,
 kGalago,
 kColobus,
 kMangabey,
 kNomascus,
 kOrangutan,
 /* AMD6000Controller */
 kPithecia,
 kBulrushes,
 kCattail,
 kHydrilla,
 kDuckweed,
 kFanwort,
 kElodea,
 kKudzu,
 kGibba,
 kLotus,
 kIpomoea,
 kMuskgrass,
 kJuncus,
 kOsmunda,
 kPondweed,
 kSpikerush,
 kTypha,
 /* AMD7000Controller */
 kRamen,
 kTako,
 kNamako,
 kAji,
 kBuri,
 kChutoro,
 kDashimaki,
 kEbi,
 kGari,
 kFutomaki,
 kHamachi,
 kOPM,
 kIkura,
 kIkuraS,
 kJunsai,
 kKani,
 kKaniS,
 kDashimakiS,
 kMaguro,
 kMaguroS,
 /* AMD8000Controller */
 kExmoor,
  kBaladi,
 /* AMD9000Controller */
 kMalteseS,
 kLagotto,
 kGreyhoundS,
 kMaltese,
  kBasset,
 kGreyhound,
  kLabrador,
 /* AMD9300Controller */
 kFleuveSWIP,
 /* AMD9500Controller */
 kAcre,
 kDayman,
 kGuariba,
 kHuallaga,
 kOrinoco,
 /* AMD9510Controller*/
 kBerbice,
 /* AMD9515Controller */
 kMazaruni,
 kLongavi,
 /* AMD9520Controller */
 kElqui,
 kCaroni,
 kFlorin,
 kRadeon, // this is absent FB if not set
 kCfgEnd
} config_name_t;

typedef struct {
 UINT16   device_id;
// UINT32   subsys_id;
 ati_chip_family_t chip_family;
 const CHAR8  *model_name;
 config_name_t  cfg_name;
} radeon_card_info_t;

typedef struct {
 DevPropDevice  *device;
 radeon_card_info_t *info;
 pci_dt_t  *pci_dev;
 UINT8   *fb;
 UINT8   *mmio;
 UINT8                 *io;
 UINT8                 *rom;
 UINT32                rom_size;
 UINT64                vram_size;
 const CHAR8           *cfg_name;
 UINT8                 ports;
 UINT32                flags;
 BOOLEAN               posted;
} card_t;

// Chip flags
/* enum radeon_chip_flags {
 RADEON_FAMILY_MASK = 0x0000ffffUL,
 RADEON_FLAGS_MASK = 0xffff0000UL,
 RADEON_IS_MOBILITY = 0x00010000UL,
 RADEON_IS_IGP = 0x00020000UL,
 RADEON_SINGLE_CRTC = 0x00040000UL,
 RADEON_IS_AGP = 0x00080000UL,
 RADEON_HAS_HIERZ = 0x00100000UL,
 RADEON_IS_PCIE = 0x00200000UL,
 RADEON_NEW_MEMMAP = 0x00400000UL,
 RADEON_IS_PCI = 0x00800000UL,
 RADEON_IS_IGPGART = 0x01000000UL,
};*/
#define MKFLAG(n)   (1 << n)
#define FLAGTRUE    MKFLAG(0)
#define EVERGREEN   MKFLAG(1)
#define FLAGMOBILE  MKFLAG(2)
#define FLAGOLD     MKFLAG(3)
#define FLAGNOTFAKE MKFLAG(4)
#define FLAGDYNAMIC MKFLAG(5)

typedef struct {
 type_t  type;
 UINT32  size;
 UINT8  *data;
} value_t;

typedef struct {
 UINT32  flags;
 BOOLEAN  all_ports;
 CHAR8  *name;
 BOOLEAN  (*get_value)(value_t *val, INTN index, BOOLEAN Sier);
 value_t  default_val;
} AtiDevProp;

BOOLEAN get_bootdisplay_val(value_t *val, INTN index, BOOLEAN Sier);
BOOLEAN get_vrammemory_val(value_t *val, INTN index, BOOLEAN Sier);
BOOLEAN get_edid_val(value_t *val, INTN index, BOOLEAN Sier);
BOOLEAN get_display_type(value_t *val, INTN index, BOOLEAN Sier);
BOOLEAN get_name_val(value_t *val, INTN index, BOOLEAN Sier);
BOOLEAN get_nameparent_val(value_t *val, INTN index, BOOLEAN Sier);
BOOLEAN get_model_val(value_t *val, INTN index, BOOLEAN Sier);
BOOLEAN get_conntype_val(value_t *val, INTN index, BOOLEAN Sier);
BOOLEAN get_vrammemsize_val(value_t *val, INTN index, BOOLEAN Sier);
BOOLEAN get_binimage_val(value_t *val, INTN index, BOOLEAN Sier);
BOOLEAN get_binimage_owr(value_t *val, INTN index, BOOLEAN Sier);
BOOLEAN get_romrevision_val(value_t *val, INTN index, BOOLEAN Sier);
BOOLEAN get_deviceid_val(value_t *val, INTN index, BOOLEAN Sier);
BOOLEAN get_mclk_val(value_t *val, INTN index, BOOLEAN Sier);
BOOLEAN get_sclk_val(value_t *val, INTN index, BOOLEAN Sier);
BOOLEAN get_refclk_val(value_t *val, INTN index, BOOLEAN Sier);
BOOLEAN get_platforminfo_val(value_t *val, INTN index, BOOLEAN Sier);
BOOLEAN get_vramtotalsize_val(value_t *val, INTN index, BOOLEAN Sier);
BOOLEAN get_dual_link_val(value_t *val, INTN index, BOOLEAN Sier);
BOOLEAN get_name_pci_val(value_t *val, INTN index, BOOLEAN Sier);

extern card_config_t card_configs[];
extern radeon_card_info_t radeon_cards[];
extern AtiDevProp ati_devprop_list[];
extern const CHAR8 *chip_family_name[];
